<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
    </style>
    <script type="application/javascript">
        const myimg = 'https://yuer.xunkids.com/article/image/DdSpqryJBOG6frNlvpzWDvGyEf4mwo2O.png'
        const myvideo = 'https://yuer.xunkids.com/article/video/V1EZXUrFQCQgn7zp7kZukRwzOUIN3Y1Z.mp4'

        function drawRect(ctx) { //矩形
            ctx.fillRect(25, 25, 100, 100); //绘制一个填充的矩形
            ctx.clearRect(45, 45, 60, 60); //清除
            ctx.strokeRect(50, 50, 50, 50); //边框
        }

        function drawPath(ctx) { //路径
            ctx.beginPath(); //新建一条路径，生成之后，图形绘制命令被指向到路径上生成路径。
            ctx.moveTo(0, 200); //将笔触移动到指定的坐标x以及y上。
            ctx.lineTo(50, 250); //绘制一条从当前位置到指定x以及y位置的直线。
            ctx.lineTo(0, 300);
            ctx.fill(); //通过填充路径的内容区域生成实心的图形。

            ctx.beginPath();
            ctx.moveTo(225, 225);
            ctx.lineTo(225, 145)
            ctx.lineTo(145, 225)
            ctx.closePath() //闭合路径之后图形绘制命令又重新指向到上下文中。
            ctx.stroke() //通过线条来绘制图形轮廓。
        }

        function drawArc(ctx) { //圆
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 3; j++) {
                    ctx.beginPath();
                    var x = 25 + j * 50; // x 坐标值
                    var y = 25 + i * 50; // y 坐标值
                    var radius = 20; // 圆弧半径
                    var startAngle = 0; // 开始点
                    var endAngle = Math.PI + (Math.PI * j) / 2; // 结束点
                    var anticlockwise = i % 2 == 0 ? false : true; // 顺时针或逆时针

                    ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);

                    if (i > 1) {
                        ctx.fill();
                    } else {
                        ctx.stroke();
                    }
                }
            }
        }

        function drawLineDash(ctx) { //虚线
            let offset = 0

            function draw1() {
                ctx.clearRect(0, 0, 120, 120); ////清除
                ctx.setLineDash([8, 2]); //指定线段与间隙的交替[线段长度,间隔长度]
                ctx.lineDashOffset = -offset; //设置起始偏移量
                ctx.strokeRect(10, 10, 100, 100); //边框
            }

            function march() {
                offset++;
                if (offset > 30) {
                    offset = 0;
                }
                draw1()
            }
            setInterval(march, 20)
        }

        function drawLinearGrad(ctx) { //线性渐变
            var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
            lingrad.addColorStop(0, '#00ABEB');
            lingrad.addColorStop(0.5, '#fff');
            lingrad.addColorStop(0.5, '#26C000');
            lingrad.addColorStop(1, '#fff');
            ctx.fillStyle = lingrad; //赋值
            ctx.fillRect(10, 10, 130, 130); //绘制一个填充的矩形

        }

        function drawRadialGradient(ctx) { //径向渐变
            var radgrad = ctx.createRadialGradient(45, 45, 10, 52, 50, 30);
            radgrad.addColorStop(0, '#A7D30C');
            radgrad.addColorStop(0.9, '#019F62');
            radgrad.addColorStop(1, 'rgba(1,159,98,0)');
            ctx.fillStyle = radgrad; //赋值
            ctx.fillRect(0, 0, 150, 150); //绘制一个填充的矩形
        }

        function drawPattern(ctx) { //图案样式
            let img = new Image();
            img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png'
            img.onload = () => {
                let tu = ctx.createPattern(img, 'repeat') //创建图案样式
                ctx.fillStyle = tu //赋值
                ctx.fillRect(0, 0, 250, 250);
            }
        }

        function drawText(ctx) { //绘制文本
            ctx.font = '26px serif'
            ctx.fillText('你好', 20, 20)
            var text = ctx.measureText("你好");
            console.log('文字的宽度是：', text.width)
        }

        function drawImage(ctx) { //使用图片
            let img = new Image();
            img.src = myimg
            img.onload = () => {
                ctx.rotate((-2 * 90 * Math.PI) / 180);
                let tu = ctx.drawImage(img, 0, 0, 500, 500, -500, -500, 500, 500)
                ctx.save()
                ctx.rotate((2 * 90 * Math.PI) / 180);
                ctx.fillText('你好', 20, 500-20)
                // ctx.restore()
                
                // ctx.rotate((-2 * 90 * Math.PI) / 180);
                // let tu = ctx.drawImage(img, 0, 0, 500, 500, -500, -500, 500, 500)
                // ctx.rotate((-3 * 90 * Math.PI) / 180);
                // let tu = ctx.drawImage(img, 0, 0, 500, 500, 0, -500, 500, 500)
                // ctx.rotate((-4 * 90 * Math.PI) / 180);
                // let tu = ctx.drawImage(img, 0, 0, 500, 500, 0, 0, 500, 500)
                
                // void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
                //source image 选取要绘制的部分：起始位置，大小
                //destination canvas 展示在canvas中：起始位置，大小
            }
        }

        function drawImageFromVideo(ctx) { //获取video的视频帧做图片源,需要播放才能用

            let video = document.getElementById("vv")
            var videoWidth = video.videoWidth;
            var videoHeight = video.videoHeight;
            var imgWidth = video.videoWidth;
            var imgHeight = video.videoHeight;

            ctx.drawImage(video, 0, 0, videoWidth, videoHeight, 0, 0, imgWidth, imgHeight)

        }

        function drawSave(ctx) { //状态的保存和恢复
            ctx.fillRect(0, 0, 150, 150); // 使用默认设置绘制一个矩形 黑
            ctx.save(); // 保存默认状态

            ctx.fillStyle = '#09F' // 在原有配置基础上对颜色做改变
            ctx.fillRect(15, 15, 120, 120); // 使用新的设置绘制一个矩形 蓝
            ctx.save(); // 保存当前状态

            ctx.fillStyle = '#FFF' // 再次改变颜色配置
            ctx.fillRect(30, 30, 90, 90); // 使用新的配置绘制一个矩形 白
            ctx.save(); // 保存当前状态

            ctx.fillStyle = '#F50' // 再次改变颜色配置
            ctx.fillRect(45, 45, 60, 60); // 使用新的配置绘制一个矩形 橙
            ctx.save(); // 保存当前状态

            ctx.restore(); //加载之前的颜色状态 橙
            ctx.restore(); // 加载加载之前之前的颜色状态 白
            ctx.restore(); //加载加载之前之前之前的颜色状态 蓝
            ctx.fillRect(60, 60, 30, 30); // 使用加载的配置绘制一个矩形

        }

        function drawTranslate(ctx) { //移动
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    ctx.save(); //记录原点（0,0）
                    ctx.fillStyle = 'rgb(' + (51 * i) + ', ' + (255 - 51 * i) + ', 255)';
                    ctx.translate(10 + j * 50, 10 + i * 50); //相对于（0,0）移动的距离
                    ctx.fillRect(0, 0, 25, 25);
                    ctx.restore(); //恢复到上一次的状态（0,0）
                }
            }
        }

        function drawRotate(ctx) {//旋转
            ctx.translate(75, 75); //移动原点到（75,75）
            for (var i = 1; i < 6; i++) { // 5层
                ctx.save();//记录原点（75,75）
                ctx.fillStyle = 'rgb(' + (51 * i) + ',' + (255 - 51 * i) + ',255)';

                for (var j = 0; j < i * 6; j++) { // draw individual dots
                    ctx.rotate(Math.PI * 2 / (i * 6));
                    ctx.beginPath();
                    ctx.arc(0, i * 12.5, 5, 0, Math.PI * 2, true);
                    ctx.fill();
                }

                ctx.restore();//恢复到上一次的状态（75,75）
            }
        }
        function drawClip(ctx){//剪裁
            let img = new Image();
            img.src = myimg
            img.onload = () => {
                
                ctx.beginPath()
                ctx.moveTo(150,200)
                ctx.lineTo(300,200)
                ctx.lineTo(350,75)
                ctx.lineTo(400,200)
                ctx.lineTo(550,200)
                ctx.lineTo(450,300)
                ctx.lineTo(500,425)
                ctx.lineTo(350,375)
                ctx.lineTo(250,425)
                ctx.lineTo(275,300)
                ctx.closePath()
                ctx.clip()
                ctx.drawImage(img,100,80)
            }
        }
        function drawBall(ctx){

        }
        function draw(ctx) {
            let canvas = document.getElementById("aa"); 
            canvas.onclick=(event)=>{
                console.log(event.x,event.y)
            }
            if (canvas.getContext) {
                var ctx = canvas.getContext('2d');
                // drawPath(ctx)
                // drawRect(ctx)
                // drawArc(ctx)
                // drawLinearGrad(ctx)
                // drawRadialGradient(ctx)
                // drawPattern(ctx)
                // drawText(ctx)
                drawImage(ctx)
                // drawImageFromVideo(ctx)
                // drawSave(ctx)
                // drawTranslate(ctx)
                // drawRotate(ctx)
                // drawClip(ctx)
            }
        }
    </script>
</head>
<!-- 不需要用别的技术栈，你试着在 Canvas 上封装一套基本元素（button label text image 等），按答主说的，先实现成立即模式，然后琢磨下怎么做成保留模式。

支持保留模式之后，拿 js 写个简单的 xml parser，把 xml 写的界面绘制到 canvas 上。

然后再研究下怎么做布局，支持简单的盒子模型+Flex就好。

然后再想办法在你的 xml 模板中支持数据绑定。 -->

<body onload="draw()" style="    display: flex;align-items: flex-start;flex-direction: column;">

    绘制矩形
    <canvas id="aa" width="600" height="600"></canvas>
    <canvas id="aa1" width="600" height="600"></canvas>
    <!-- <video controls autoplay width="250" id="vv"
        src="https://yuer.xunkids.com/article/video/V1EZXUrFQCQgn7zp7kZukRwzOUIN3Y1Z.mp4" type="video/mp4">

        Sorry, your browser doesn't support embedded videos.
    </video> -->
</body>

</html>